package com.maxafaa.dodgeballoon;

/*
 * @author mrdmgdd
 */

public class PhysicObject {
    
    private double m_current_position_x;
    private double m_current_position_y;
    private double m_init_position_x;
    private double m_init_position_y;
    private double m_current_velocity_x;
    private double m_current_velocity_y;
    private double m_init_velocity_x;
    private double m_init_velocity_y;
    private double m_release_time;
    private double m_survival_time;
    private int m_bound_rect_x;
    private int m_bound_rect_y;
    private int m_bound_rect_width;
    private int m_bound_rect_height;
    private double m_elastic;
    private double m_friction;
    private int m_object_radius;
    private boolean m_need_check_bound;
    private final int M_DEFAULT_RADIUS = 10;
    private final double M_DEFAULT_ELASTIC =  0.5;//default 0.95
    private final double M_DEFAULT_FRICTION = 1.0;//default 1.0
    private boolean is_going_down;
    private boolean is_going_left;

    public PhysicObject(int ini_position_x, int ini_position_y, double ini_power, double ini_angle_in_radian){
        m_release_time = System.currentTimeMillis();
        m_survival_time = System.currentTimeMillis();
        m_current_position_x = m_init_position_x = ini_position_x;
        m_current_position_y = m_init_position_y = ini_position_y;
        m_current_velocity_x = m_init_velocity_x = ini_power*Math.cos(ini_angle_in_radian);
        m_current_velocity_y = m_init_velocity_y = ini_power*Math.sin(ini_angle_in_radian);
        m_need_check_bound = false;
        m_object_radius = M_DEFAULT_RADIUS;
        m_elastic = M_DEFAULT_ELASTIC;
        m_friction = M_DEFAULT_FRICTION;
        is_going_down = true;
        is_going_left = false;
    }

    public PhysicObject(int ini_position_x, int ini_position_y, double ini_power, double ini_angle_in_radian, int radius){
        m_release_time = System.currentTimeMillis();
        m_survival_time = System.currentTimeMillis();
        m_current_position_x = m_init_position_x = ini_position_x;
        m_current_position_y = m_init_position_y = ini_position_y;
        m_current_velocity_x = m_init_velocity_x = ini_power*Math.cos(ini_angle_in_radian);
        m_current_velocity_y = m_init_velocity_y = ini_power*Math.sin(ini_angle_in_radian);
        m_need_check_bound = false;
        m_object_radius = radius;
        m_elastic = M_DEFAULT_ELASTIC;
        m_friction = M_DEFAULT_FRICTION;
        is_going_down = true;
        is_going_left = false;
    }

    public PhysicObject(int ini_position_x, int ini_position_y, double ini_power, double ini_angle_in_radian, int bound_width, int bound_height){
        m_release_time = System.currentTimeMillis();
        m_survival_time = System.currentTimeMillis();
        m_current_position_x = m_init_position_x = ini_position_x;
        m_current_position_y = m_init_position_y = ini_position_y;
        m_current_velocity_x = m_init_velocity_x = ini_power*Math.cos(ini_angle_in_radian);
        m_current_velocity_y = m_init_velocity_y = ini_power*Math.sin(ini_angle_in_radian);
        m_object_radius = M_DEFAULT_RADIUS;
        m_bound_rect_x = 0;
        m_bound_rect_y = 0;
        m_bound_rect_width = bound_width;
        m_bound_rect_height = bound_height;
        m_need_check_bound = true;
        m_elastic = M_DEFAULT_ELASTIC;
        m_friction = M_DEFAULT_FRICTION;
        is_going_down = true;
        is_going_left = false;
    }

    public PhysicObject(int ini_position_x, int ini_position_y, double ini_power, double ini_angle_in_radian, int radius, int bound_width, int bound_height){
        m_release_time = System.currentTimeMillis();
        m_survival_time = System.currentTimeMillis();
        m_current_position_x = m_init_position_x = ini_position_x;
        m_current_position_y = m_init_position_y = ini_position_y;
        m_current_velocity_x = m_init_velocity_x = ini_power*Math.cos(ini_angle_in_radian);
        m_current_velocity_y = m_init_velocity_y = ini_power*Math.sin(ini_angle_in_radian);
        m_object_radius = radius;
        m_bound_rect_x = 0;
        m_bound_rect_y = 0;
        m_bound_rect_width = bound_width;
        m_bound_rect_height = bound_height;
        m_need_check_bound = true;
        m_elastic = M_DEFAULT_ELASTIC;
        m_friction = M_DEFAULT_FRICTION;
        is_going_down = true;
        is_going_left = false;
    }

    public PhysicObject(int ini_position_x, int ini_position_y, double ini_power, double ini_angle_in_radian, int bound_x, int bound_y, int bound_width, int bound_height){
        m_release_time = System.currentTimeMillis();
        m_survival_time = System.currentTimeMillis();
        m_current_position_x = m_init_position_x = ini_position_x;
        m_current_position_y = m_init_position_y = ini_position_y;
        m_current_velocity_x = m_init_velocity_x = ini_power*Math.cos(ini_angle_in_radian);
        m_current_velocity_y = m_init_velocity_y = ini_power*Math.sin(ini_angle_in_radian);
        m_object_radius = M_DEFAULT_RADIUS;
        m_bound_rect_x = bound_x;
        m_bound_rect_y = bound_y;
        m_bound_rect_width = bound_width;
        m_bound_rect_height = bound_height;
        m_need_check_bound = true;
        m_elastic = M_DEFAULT_ELASTIC;
        m_friction = M_DEFAULT_FRICTION;
        is_going_down = true;
        is_going_left = false;
    }

    public PhysicObject(int ini_position_x, int ini_position_y, double ini_power, double ini_angle_in_radian, int radius, int bound_x, int bound_y, int bound_width, int bound_height){
        m_release_time = System.currentTimeMillis();
        m_survival_time = System.currentTimeMillis();
        m_current_position_x = m_init_position_x = ini_position_x;
        m_current_position_y = m_init_position_y = ini_position_y;
        m_current_velocity_x = m_init_velocity_x = ini_power*Math.cos(ini_angle_in_radian);
        m_current_velocity_y = m_init_velocity_y = ini_power*Math.sin(ini_angle_in_radian);
        m_object_radius = radius;
        m_bound_rect_x = bound_x;
        m_bound_rect_y = bound_y;
        m_bound_rect_width = bound_width;
        m_bound_rect_height = bound_height;
        m_need_check_bound = true;
        m_elastic = M_DEFAULT_ELASTIC;
        m_friction = M_DEFAULT_FRICTION;
        is_going_down = true;
        is_going_left = false;
    }
    
    public int getPositionX(){
        return (int)Math.round(m_current_position_x);
    }   

    public int getPositionY(){        
        return (int)Math.round(m_current_position_y);
    }
    
    public double getVelocityX(){
        return m_current_velocity_x;
    }

    public double getVelocityY(){
        return m_current_velocity_y;
    }
    
    public double getVelocityIniX(){
        return m_init_velocity_x;
    }

    public double getVelocityIniY(){
        return m_init_velocity_y;
    }
    
    public void setVelocityIniX(double m_init_velocity_x){
    	this.m_init_velocity_x = m_init_velocity_x;
    }

    public void setVelocityIniY(double m_init_velocity_y){
    	this.m_init_velocity_y = m_init_velocity_y;
    }

    public void setRadius(int new_radius){
        m_object_radius = new_radius;
    }

    public int getRadius(){
        return m_object_radius;
    }

    public double getReleaseTime(){
        return m_release_time;
    }
    
    public double getSurvivalTime(){
        return m_survival_time;
    }

    public void setBoundRect(int rect_x, int rect_y, int rect_width, int rect_height){
        m_bound_rect_x = rect_x;
        m_bound_rect_y = rect_y;
        m_bound_rect_width = rect_width;
        m_bound_rect_height = rect_height;
        m_need_check_bound = true;
    }

    public void Update(){
        double elapsed_time = (System.currentTimeMillis() - m_release_time)*0.01;
        double distance_position_x = (m_init_velocity_x * elapsed_time);//new_x = v0x * time;
        double distance_position_y = (m_init_velocity_y * elapsed_time + 0.5 * (-9.8) * elapsed_time * elapsed_time);//new_y = v0y * time + 1/2 * gravity(-9.8) * time * time;
        
        //recalculate velocity
//        m_current_velocity_x = m_velocity_init_x;//no change with time, no need to compile this line
        m_current_velocity_y = m_init_velocity_y + (-9.8) * elapsed_time;// vt = v0t + gravity*time
        if(m_init_velocity_x < 0)
            is_going_left = true;
        else if(m_init_velocity_x > 0)
            is_going_left = false;
        if(m_current_velocity_y < 0)
            is_going_down = true;        
        
        m_current_position_x = m_init_position_x + distance_position_x;
        m_current_position_y = m_init_position_y - distance_position_y;//vi chieu duong huong xuong nen phai tru
        
        //bound check
        if(m_need_check_bound){
            //down
            if((m_current_position_y + m_object_radius) >= (m_bound_rect_y + m_bound_rect_height)){
                if(is_going_down){
                    m_init_velocity_y = -m_current_velocity_y * m_elastic / m_friction;
                    is_going_down = false;
                }
                m_init_velocity_x = m_init_velocity_x * m_elastic / m_friction;
                m_init_position_x = m_current_position_x;
                m_init_position_y = m_current_position_y;
                m_release_time = System.currentTimeMillis();
            }
            //left
            if((m_current_position_x - m_object_radius) <= m_bound_rect_x){
                m_init_velocity_y = m_current_velocity_y;
                if(is_going_left){
                    m_current_velocity_x = m_init_velocity_x = -m_init_velocity_x * m_elastic / m_friction;
                    is_going_left = false;
                }
                m_init_position_x = m_current_position_x;
                m_init_position_y = m_current_position_y;
                m_release_time = System.currentTimeMillis();
            }
            //right
            if((m_current_position_x + m_object_radius) >= (m_bound_rect_x + m_bound_rect_width)){
                m_init_velocity_y = m_current_velocity_y;
                if(!is_going_left){
                    m_current_velocity_x = m_init_velocity_x = -m_init_velocity_x * m_elastic / m_friction;
                    is_going_left = true;
                }
                m_init_position_x = m_current_position_x;
                m_init_position_y = m_current_position_y;
                m_release_time = System.currentTimeMillis();
            }
        }
        
    }
    public void Destroy(){
        m_current_position_x = 0;
        m_current_position_y = 0;
        m_init_position_x = 0;
        m_init_position_y = 0;
        m_current_velocity_x = 0;
        m_current_velocity_y = 0;
        m_init_velocity_x = 0;
        m_init_velocity_y = 0;
        m_release_time = 0;
        m_survival_time = 0;
        m_bound_rect_x = 0;
        m_bound_rect_y = 0;
        m_bound_rect_width = 0;
        m_bound_rect_height = 0;
        m_elastic = 0;
        m_friction = 0;
        m_object_radius = 0;
        m_need_check_bound = false;
        is_going_down = false;
    }
}